//
//  TryHoneLogHelper.m
//  TryHone
//
//  Created by TryHone on 17/5/24.
//  Copyright © 2017年 TryHone. All rights reserved.
//

#import "JFLogHelper.h"
#import "JFFileHelper.h"
#import "JFDateHelper.h"
#import "JFStringHelper.h"
#import "JFBase.h"
#import "JFMacro.h"
#include <pthread.h>
#import "Logan.h"
#include <zlib.h>
#import <CommonCrypto/CommonCryptor.h>

@implementation JFLogModel
-(void)setTxtLog:(NSString *)txtLog{
    _txtLog=txtLog;
    _istxt=YES;
}
-(void)setDictLog:(NSDictionary *)dictLog{
    _dictLog=dictLog;
    _istxt=NO;
}
@end


@interface JFLogHelper();
//日志文件缓存目录
@property(nonatomic,copy) NSString* logPath;
@end


@implementation JFLogHelper{
    NSMutableArray* _logQueue;
    NSCondition *_condition;
    
}


/**
 *  @author Alan, 16-12-23 15:12:50
 *
 *  @brief 获取日志类
 */
+(JFLogHelper *)shareInstance
{
    static dispatch_once_t once;
    static id instance;
    dispatch_once(&once, ^{
        instance = [[self alloc]init];
        
    });
    return instance;
}
-(instancetype)init{
    self=[super init];
    
    if (self) {
        _logQueue=[[NSMutableArray alloc] init];
        _condition = [[NSCondition alloc] init];
//        for (int i=0; i<3; i++) {
         NSThread *logthread = [[NSThread alloc] initWithTarget:self selector:@selector(logCustomer) object:nil];
         [logthread start];
//        }
        //启动的时候插件文件目录
        NSString* doc=[JFFileHelper documentFolder];//获取doc目录
        NSString* log=[doc stringByAppendingPathComponent:@"log"];
        _logPath = log;
        [JFFileHelper createFile:log isDirectory:YES];
        
        //美团日志引擎
        NSData *keydata = [@"0123456789012345" dataUsingEncoding:NSUTF8StringEncoding];
        NSData *ivdata = [@"0123456789012345" dataUsingEncoding:NSUTF8StringEncoding];
        uint64_t file_max = 10 * 1024 * 1024;
        loganInit(keydata, ivdata, file_max);
        loganSetMaxReversedDate(3);
        
        
    }
    return self;
}

-(void)setIsDebug:(BOOL)isDebug{
    _isDebug = isDebug;
    loganUseASL(isDebug);
}
/**
 *  @author Alan, 16-12-23 15:12:05
 *
 *  @brief 消费日志
 */
-(void)logCustomer{
    while (YES) {
        [_condition lock];
        while ([_logQueue count] == 0) {
            [_condition wait];
        }
        JFLogModel* data=[_logQueue objectAtIndex:0];
        if(!data.isDealWith){
            data.isDealWith = YES;
            [self dealWithLog:data];
            if(data.type == LogType_Console){//不阻塞的走
                [_logQueue removeObject:data];
            }else{//阻塞走下面
               [_logQueue replaceObjectAtIndex:0 withObject:data];
            }
            
        }
        [_condition unlock];
    }
}
-(void)writeLog:(JFLogModel*)model{

    [_condition lock];
    [_logQueue addObject:model];
    [_condition broadcast];
    [_condition unlock];
}

-(void)dealWithLog:(JFLogModel*)modle{
    switch (modle.type) {
        case LogType_Console:
        {
            [self dealWithConsoleLog:modle];
        } break;
        case LogType_File:{
            [self dealWithFileLog:modle];
        }
        default:
            break;
    }
}

-(void)dealWithConsoleLog:(JFLogModel*)modle{
    if (modle.istxt) {
        logan(1, modle.txtLog);
    }else{
        logan(1, [modle.dictLog JSONString]);
    }
}

-(void)clearMemory{
    if (_logQueue&&_logQueue.count) {
        [_logQueue removeAllObjects];
    }
}
-(void)dealWithFileLog:(JFLogModel*)modle{
    NSString*  filename=[JFDateHelper formatDate:[NSDate date]];//用日期做文件名每天一个文件
    NSString* doc=[JFFileHelper documentFolder];//获取doc目录
    NSString* log=[doc stringByAppendingPathComponent:@"/log"];
    NSString* path=[log stringByAppendingString:[NSString stringWithFormat:@"/%@",filename]];
    [JFFileHelper createFile:path isDirectory:NO];//创建文件，已创建则跳过
    AWWeakSelf(self)
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSString *time = [JFDateHelper formatDate:[NSDate date] format:@"yyyy-MM-dd HH:mm:ss"];
        if (modle.istxt) {
            NSString * mapStr =  [NSString stringWithFormat:@"%@--time:%@\r\n",modle.txtLog,time];
            [JFFileHelper writeContent:mapStr inFile:path isExtend:YES];
        }else{
            NSString *  mapStr = [JFLogHelper convertToJSONData:modle.dictLog];
            if(mapStr&&mapStr.length){
                mapStr =  [NSString stringWithFormat:@"%@--time:%@\r\n",mapStr,time];
                [JFFileHelper writeContent:mapStr inFile:path isExtend:YES];
            }
        }
        [weakself removeObject:modle];
    });
}
-(void)removeObject:(JFLogModel*)modle{
    [_condition lock];
    [_logQueue removeObject:modle];
    [_condition unlock];
}
+ (NSString*)convertToJSONData:(id)infoDict
{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:infoDict
                                                       options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                         error:&error];
    
    NSString *jsonString = @"";
    
    if (! jsonData)
    {
        NSLog(@"Got an error: %@", error);
    }else
    {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    jsonString = [jsonString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];  //去除掉首尾的空白字符和换行字符
    
    [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    
    return jsonString;
}
//类方法
+(void)writeLog:(JFLogModel*)model{
    [[JFLogHelper shareInstance] writeLog:model];
}

+(void)stringWriteLogToFile:(NSString*)str{
    if(str && [str isKindOfClass:[NSString class]] && str.length){
        JFLogModel* model = [[JFLogModel alloc] init];
        model.txtLog = str;
        model.type = LogType_File;
        [[JFLogHelper shareInstance] writeLog:model];
    }

}
+(void)mapWriteLogToFile:(NSDictionary*)dict{
    JFLogModel* model = [[JFLogModel alloc] init];
    model.dictLog = dict;
    model.type = LogType_File;
    [[JFLogHelper shareInstance] writeLog:model];
}

+ (void)dataWriteLogToFile:(id)data{
    if (data) {
        if ([data isKindOfClass:[NSString class]]){
            [self stringWriteLogToFile:(NSString*)data];
        }else if ([data isKindOfClass:[NSDictionary class]]|| [@"__NSDictionaryI" isEqualToString:NSStringFromClass([data class])] ||  [@"__NSDictionaryM" isEqualToString:NSStringFromClass([data class])]){
            [self mapWriteLogToFile:(NSDictionary*)data];
        }else if ([data isKindOfClass:[NSArray class]] || [@"__NSArrayI" isEqualToString:NSStringFromClass([data class])] ||  [@"__NSArrayM" isEqualToString:NSStringFromClass([data class])]){
            NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
            dict[@"msg"] = data;
            [self mapWriteLogToFile:dict];
        }
    }
}

+(void)stringWriteLogToConsole:(NSString*)str{
    JFLogModel* model = [[JFLogModel alloc] init];
    model.txtLog = str;
    model.type = LogType_Console;
    [[JFLogHelper shareInstance] writeLog:model];
}
+(void)mapWriteLogToConsole:(NSDictionary*)dict{
    JFLogModel* model = [[JFLogModel alloc] init];
    model.dictLog = dict;
    model.type = LogType_Console;
    [[JFLogHelper shareInstance] writeLog:model];
}

/**
 *  @author Alan, 16-12-23 17:12:46
 *
 *  @brief 同步把字符串输出到控制台
 *
 *  @param str 字符串
 */
+ (void)stringSyncWriteLogToConsole:(NSString*)str{
     logan(1, str);
}
/**
 *  @author Alan, 16-12-26 13:12:02
 *
 *  @brief 同步把字典写入到控制台
 *
 *  @param dict 字典入参
 */
+ (void)mapSyncWriteLogToConsole:(NSDictionary*)dict{
    NSString * jsonStr = [dict JSONString];
    logan(1, jsonStr);
}
//向控制台写日志
+ (void)logToConsole:(id)data{
    if(data){
        JFLogModel* model = [[JFLogModel alloc] init];
        model.type = LogType_Console;
        if([data isKindOfClass:[NSString class]]){
          model.txtLog = data;
          [[JFLogHelper shareInstance] writeLog:model];
        }else if ([data  isKindOfClass:[NSDictionary class]]){
            model.dictLog = data;
            [[JFLogHelper shareInstance] writeLog:model];
        } else if ([data isKindOfClass:[NSArray class]]){
            NSArray * strArr = [[NSArray alloc] initWithArray:[data copy]];
            if(strArr.count){
              NSString *string = [strArr componentsJoinedByString:@","];
              model.txtLog = string;
              [[JFLogHelper shareInstance] writeLog:model];
            }
        }
        
    }
}
//同步向控制台写日志
+ (void)syncLogToConsole:(id)data{
    
    if ([data isKindOfClass:[NSString class]]) {
        NSString * jsonStr = (NSString*)data;
        logan(1, jsonStr);
    }else if ([data isKindOfClass:[NSDictionary class]]){
        NSDictionary * dict = (NSDictionary*)data;
        NSString * jsonStr = [dict JSONString];
        logan(1, jsonStr);
    }else if ([data isKindOfClass:[NSArray class]]){
        NSArray * arr = (NSArray*)data;
        NSString * jsonStr = [arr JSONString];
        logan(1, jsonStr);
    }else{
        AWLog(@"%@",data);
    }
    
}
+ (void)uploadLogWithDate:(NSString*)date result:(void(^)(NSError * error))result{
    loganFlush();
    NSString * data = date;
    if ([JFStringHelper isEmpty:date]) {
        data = loganTodaysDate();
    }
    
    loganUploadFilePath(data, ^(NSString *_Nullable filePatch) {
           if (filePatch == nil) {
               NSError * error = [NSError errorWithDomain:@"" code:-1 userInfo:@{@"msg":@"暂无改日期日志"}];
               if (result) {
                   result(error);
               }
               return;
           }
           NSString *urlStr = [NSString stringWithFormat:@"http://%@:3000/logupload", @"10.1.2.217"];
           NSURL *url = [NSURL URLWithString:urlStr];
           NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
           [req setHTTPMethod:@"POST"];
           [req addValue:@"binary/octet-stream" forHTTPHeaderField:@"Content-Type"];
           NSURL *fileUrl = [NSURL fileURLWithPath:filePatch];
           NSURLSessionUploadTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:req fromFile:fileUrl completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
               if (result) {
                   result(error);
               }
           }];
           [task resume];
       });
}
//向控制台写日志
+ (void)logToFile:(id)data{
    if(data){
        JFLogModel* model = [[JFLogModel alloc] init];
        model.type = LogType_File;
        if([data isKindOfClass:[NSString class]]){
            model.txtLog = data;
            [[JFLogHelper shareInstance] writeLog:model];
        }else if ([data  isKindOfClass:[NSDictionary class]]){
            model.dictLog = data;
            [[JFLogHelper shareInstance] writeLog:model];
        } else if ([data isKindOfClass:[NSArray class]]){
            NSArray * strArr = [[NSArray alloc] initWithArray:[data copy]];
            if(strArr.count){
                NSString *string = [strArr componentsJoinedByString:@","];
                model.txtLog = string;
                [[JFLogHelper shareInstance] writeLog:model];
            }
        }
        
    }
}

//清楚硬盘上的日志缓存
+(void)clearDiskCacheFile{
    NSString*  logpath = [JFLogHelper shareInstance].logPath;
    if ([JFStringHelper isNotEmpty:logpath]) {
       [JFFileHelper removeFile:logpath];
    }
}
//清除所有的缓存
+(void)clearAllLogCache{
    [[JFLogHelper shareInstance] clearMemory];
    [JFLogHelper clearAllLogCache];
    loganClearAllLogs();
}

//获取日志缓存目录
+ (NSString*)logCachePath{
    return [JFLogHelper shareInstance].logPath;
}

@end
